Skip to content

feat(spec,verify): prove-it-runs proof field + ratchet, binding 4 high-risk classes (ADR-0054 #1 + Phase 2)#2045

Merged
os-zhuang merged 4 commits into
mainfrom
claude/lucid-gauss-t7dd3z
Jun 19, 2026
Merged

feat(spec,verify): prove-it-runs proof field + ratchet, binding 4 high-risk classes (ADR-0054 #1 + Phase 2)#2045
os-zhuang merged 4 commits into
mainfrom
claude/lucid-gauss-t7dd3z

Conversation

@os-zhuang

@os-zhuang os-zhuang commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

What & why

ADR-0054 follow-up (1) + Phase 2: define the authoritative high-risk-class list and add the proof field + ratchet to the spec liveness gate, then bind the high-risk classes — including new runtime proofs/bindings for flow nodes and analytics.

Until now, a live classification in the liveness ledger meant only a static pointer to a consumer — proof that something reads the property. That is necessary but not sufficient: a property can be live at every layer yet broken end-to-end (the break lives in the engine↔driver↔service↔HTTP integration — #2018, the rating/slider/toggle fidelity leak). ADR-0054 adds the third leg — prove-it-runs: for high-risk authorable classes, live must carry a proof (a @objectstack/dogfood test that authors the property against the real in-process stack and asserts the runtime outcome).

The earlier ADR-0054 follow-ups are already merged: field-fidelity fix + field-zoo (#2025/#2022), tz-bucketing proof (#2018), the @objectstack/verify engine (#2041), and the #1994 RLS seed + multi-user harness (#2024/#2032). This adds the missing keystone (the ratchet) and binds four classes.

Design (the proof contract)

  • proof = "<repo-relative-file>#<proof-id>". The dogfood test self-declares the id with a greppable // @proof: <id> tag near its top.
  • Validation is STATIC — the gate checks the file exists and declares the tag; it never runs the test (that's the dogfood gate's job), keeping the liveness gate seconds-cheap (ADR §4). A greppable tag (not a test title) is deliberate: field-zoo titles are generated in a loop.
  • Bidirectional integrity. A bound live entry must carry a valid proof of its own class. The reverse check flags any @proof: tag under packages/dogfood/test/** not registered in proof-registry.mts (warning).
  • Gate also triggers on packages/dogfood/**, so deleting/renaming a proof re-runs the check and a dangling reference is caught.

The ratchet — four classes bound (ADR §3)

A class is CI-enforced only once it has both a runtime proof and a governed ledger entry to carry it.

High-risk class Bound? Ledger binding Proof
Field types ✅ enforced field.type field-zoo-roundtrip#field-type-roundtrip
RLS / sharing ✅ enforced permission.rowLevelSecurity.using rls-fixture#rls-by-id-write
Flow nodes ✅ enforced flow.nodes.type flow-node#flow-node-execution (new proof)
Analytics dims/measures ✅ enforced dataset.dimensions.dateGranularity analytics-timezone#analytics-tz-bucketing (newly bound)
Form layout/section/widget ⛔ pending none yet (form surface not governed)

Phase 2 — new this PR

Flow-node runtime proof. Flow execution wasn't reachable through the harness (bootStack registered no automation service). Mirroring how the RLS proof first needed a multi-user harness capability:

  • @objectstack/verify: bootStack gains an opt-in automation flag that registers @objectstack/service-automation; the app's flows are then pulled from the registry and their nodes execute. Default off — standard boot stays lean.
  • dogfood proof: a self-contained fixture (one object + one autolaunched flow whose update_record node stamps a record) triggers the flow over HTTP and asserts both directions — the targeted record IS stamped (node executed) and a bystander is not (the input variable wired into the node's filter, not a blanket update).

Govern dataset + bind analytics. The analytics proof existed (#2018) but its surface wasn't governed. This adds liveness/dataset.json (all 19 authorable props classified with file:line evidence from a consumer audit; 26 live, 1 dead) and binds dataset.dimensions.dateGranularity to the tz-bucketing proof.

Verification (all local, green)

  • pnpm --filter @objectstack/spec check:liveness → green; 11 governed types; reports the 4 bound classes.
  • Red paths confirmed: dangling proof tag → fail; bound live with no proof → fail; orphan tag → warning.
  • 17 unit + wiring tests (proof-registry.test.ts).
  • Flow-node proof runs green; analytics tz proof runs green; full dogfood suite 59/59.

🤖 Generated with Claude Code

…(ADR-0054 #1)

ADR-0054 follow-up (1): the liveness ledger's `live` meant only a static
consumer pointer — necessary but not sufficient, since a property can be live at
every layer yet broken end-to-end. This adds the third leg: high-risk authorable
properties must carry a `proof` (a dogfood test reference) that asserts the
runtime outcome.

- proof-registry.mts: the authoritative high-risk-class list (field types,
  analytics, RLS, flow nodes, form widgets) + which classes the ratchet enforces
  this phase. Field types and RLS are bound (matrix exists AND surface governed);
  analytics/flow/form are listed-but-blocked with honest reasons (their surface
  isn't governed yet / no proof yet — Phase 2).
- check-liveness.mts: a bound `live` entry must carry a valid `proof` of its own
  class. Validation is STATIC (file exists + declares the `@proof: <id>` tag) so
  the gate stays seconds-cheap; running the proof remains the dogfood gate's job.
  Reverse check flags unregistered `@proof:` tags.
- Ledger: field.type → field-zoo proof; permission.rowLevelSecurity.using →
  #1994 RLS proof. Dogfood proofs self-declare their `@proof:` tag.
- Gate now also triggers on packages/dogfood/** so deleting/renaming a proof
  re-runs the check and the dangling reference is caught.
- 15 unit + wiring tests; README documents the contract and ratchet.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XVdnfUAx85amkerym26vdx
@vercel

vercel Bot commented Jun 19, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
spec Ready Ready Preview, Comment Jun 19, 2026 10:33am

Request Review

@github-actions github-actions Bot added documentation Improvements or additions to documentation ci/cd tests tooling size/l labels Jun 19, 2026
@github-actions

github-actions Bot commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 3 package(s): @objectstack/dogfood, @objectstack/spec, @objectstack/verify.

89 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:

  • content/docs/concepts/architecture.mdx (via @objectstack/spec)
  • content/docs/concepts/cloud-artifact-api.mdx (via packages/spec)
  • content/docs/concepts/cluster-semantics.mdx (via @objectstack/spec)
  • content/docs/concepts/design-principles.mdx (via packages/spec)
  • content/docs/concepts/implementation-status.mdx (via @objectstack/spec)
  • content/docs/concepts/index.mdx (via @objectstack/spec)
  • content/docs/concepts/metadata-driven.mdx (via @objectstack/spec)
  • content/docs/concepts/metadata-lifecycle.mdx (via packages/spec)
  • content/docs/concepts/north-star.mdx (via packages/spec)
  • content/docs/concepts/packages.mdx (via @objectstack/spec)
  • content/docs/concepts/setup-app.mdx (via @objectstack/spec)
  • content/docs/concepts/skills.mdx (via @objectstack/spec)
  • content/docs/concepts/webhook-delivery.mdx (via @objectstack/spec)
  • content/docs/getting-started/architecture.mdx (via @objectstack/spec)
  • content/docs/getting-started/cli.mdx (via @objectstack/spec)
  • content/docs/getting-started/core-concepts.mdx (via @objectstack/spec)
  • content/docs/getting-started/examples.mdx (via @objectstack/spec)
  • content/docs/getting-started/quick-start.mdx (via @objectstack/spec)
  • content/docs/guides/adding-a-metadata-type.mdx (via @objectstack/spec)
  • content/docs/guides/ai-capabilities.mdx (via @objectstack/spec)
  • content/docs/guides/airtable-dashboard-analysis.mdx (via @objectstack/spec)
  • content/docs/guides/analytics-datasets.mdx (via @objectstack/spec)
  • content/docs/guides/api-reference.mdx (via @objectstack/spec)
  • content/docs/guides/business-logic.mdx (via @objectstack/spec)
  • content/docs/guides/cheatsheets/backward-compatibility.mdx (via @objectstack/spec)
  • content/docs/guides/cheatsheets/error-catalog.mdx (via @objectstack/spec)
  • content/docs/guides/cheatsheets/field-type-gallery.mdx (via @objectstack/spec)
  • content/docs/guides/cheatsheets/field-validation-rules.mdx (via @objectstack/spec)
  • content/docs/guides/cheatsheets/permissions-matrix.mdx (via @objectstack/spec)
  • content/docs/guides/cheatsheets/protocol-diagram.mdx (via packages/spec)
  • content/docs/guides/cheatsheets/query-cheat-sheet.mdx (via @objectstack/spec)
  • content/docs/guides/cheatsheets/quick-reference.mdx (via @objectstack/spec)
  • content/docs/guides/client-sdk.mdx (via @objectstack/spec)
  • content/docs/guides/common-patterns.mdx (via @objectstack/spec)
  • content/docs/guides/contracts/auth-service.mdx (via packages/spec)
  • content/docs/guides/contracts/cache-service.mdx (via packages/spec)
  • content/docs/guides/contracts/data-engine.mdx (via @objectstack/spec)
  • content/docs/guides/contracts/index.mdx (via @objectstack/spec)
  • content/docs/guides/contracts/metadata-service.mdx (via packages/spec)
  • content/docs/guides/contracts/storage-service.mdx (via packages/spec)
  • content/docs/guides/data-modeling.mdx (via @objectstack/spec)
  • content/docs/guides/deployment-vercel.mdx (via @objectstack/spec)
  • content/docs/guides/driver-configuration.mdx (via @objectstack/spec)
  • content/docs/guides/error-handling-client.mdx (via @objectstack/spec)
  • content/docs/guides/error-handling-server.mdx (via @objectstack/spec)
  • content/docs/guides/formula.mdx (via @objectstack/spec)
  • content/docs/guides/hook-bodies.mdx (via packages/spec)
  • content/docs/guides/kernel-services.mdx (via @objectstack/spec)
  • content/docs/guides/metadata/dashboard.mdx (via @objectstack/spec)
  • content/docs/guides/metadata/field.mdx (via @objectstack/spec)
  • content/docs/guides/metadata/flow.mdx (via @objectstack/spec)
  • content/docs/guides/metadata/index.mdx (via @objectstack/spec)
  • content/docs/guides/metadata/object.mdx (via @objectstack/spec)
  • content/docs/guides/metadata/validation.mdx (via @objectstack/spec)
  • content/docs/guides/metadata/workflow.mdx (via @objectstack/spec)
  • content/docs/guides/packages.mdx (via @objectstack/spec)
  • content/docs/guides/plugin-development.mdx (via @objectstack/spec)
  • content/docs/guides/plugins.mdx (via @objectstack/spec)
  • content/docs/guides/project-scoping.mdx (via @objectstack/spec)
  • content/docs/guides/public-forms.mdx (via @objectstack/spec)
  • content/docs/guides/runtime-services/email-service.mdx (via packages/spec)
  • content/docs/guides/runtime-services/index.mdx (via packages/spec)
  • content/docs/guides/runtime-services/queue-service.mdx (via packages/spec)
  • content/docs/guides/runtime-services/sharing-service.mdx (via packages/spec)
  • content/docs/guides/runtime-services/storage-service.mdx (via packages/spec)
  • content/docs/guides/security.mdx (via @objectstack/spec)
  • content/docs/guides/seed-data.mdx (via @objectstack/spec)
  • content/docs/guides/skills.mdx (via @objectstack/spec)
  • content/docs/guides/standards.mdx (via @objectstack/spec)
  • content/docs/guides/troubleshooting.mdx (via @objectstack/spec)
  • content/docs/protocol/knowledge.mdx (via @objectstack/spec)
  • content/docs/protocol/objectos/config-resolution.mdx (via @objectstack/spec)
  • content/docs/protocol/objectos/i18n-standard.mdx (via @objectstack/spec)
  • content/docs/protocol/objectos/lifecycle.mdx (via @objectstack/spec)
  • content/docs/protocol/objectos/plugin-spec.mdx (via @objectstack/spec)
  • content/docs/protocol/objectos/runtime-capabilities.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/index.mdx (via packages/spec)
  • content/docs/protocol/objectql/query-syntax.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/schema.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/security.mdx (via packages/spec)
  • content/docs/protocol/objectql/state-machine.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/actions.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/concept.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/index.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/layout-dsl.mdx (via packages/spec)
  • content/docs/protocol/objectui/record-alert.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/widget-contract.mdx (via @objectstack/spec)
  • content/docs/releases/index.mdx (via @objectstack/spec)
  • content/docs/releases/v9.mdx (via @objectstack/spec)

Advisory only. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

…f (ADR-0054 Phase 2)

Phase 2 extends the prove-it-runs ratchet to the flow-node class.

- verify: bootStack gains an opt-in `automation` flag that registers
  @objectstack/service-automation, so authored flows are pulled from the registry
  and POST /automation/:name/trigger runs their nodes. Without it, flow execution
  was unreachable through the harness (the dispatcher's automation routes resolved
  no service). Mirrors the existing `multiTenant`/`security` opt-ins; default off.
- dogfood: a self-contained flow fixture (one object + one autolaunched flow whose
  update_record node stamps a record) + the flow-node proof. It authors the flow,
  triggers it over HTTP, and asserts both directions — the targeted record is
  stamped (node executed) AND a bystander is untouched (the input variable wired
  into the node filter, not a blanket update). Runs green end-to-end.
- spec: flow-node class is now `bound` in proof-registry.mts; flow.nodes.type
  carries the proof; the liveness gate enforces it. Three classes now bound:
  field types, RLS, flow nodes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XVdnfUAx85amkerym26vdx
@github-actions github-actions Bot added the dependencies Pull requests that update a dependency file label Jun 19, 2026
@os-zhuang os-zhuang changed the title feat(spec): prove-it-runs proof field + ratchet for the liveness gate (ADR-0054 #1) feat(spec,verify): prove-it-runs proof field + ratchet, and the flow-node Phase 2 proof (ADR-0054 #1 + Phase 2) Jun 19, 2026
…0054)

Unlocks the analytics binding that was previously blocked because its authorable
surface wasn't governed.

- Govern the `dataset` metadata type: new liveness/dataset.json classifies all 19
  authorable props with file:line evidence from the analytics service consumer
  audit (26 live, 1 dead — measures.certified has no runtime consumer). `dataset`
  added to GOVERNED in check-liveness.mts.
- Bind the analytics class: dataset.dimensions.dateGranularity carries the
  tz-bucketing proof (#1982/#2018) — the property whose org-timezone day-bucket
  behavior the proof asserts. proof-registry.mts flips analytics to bound.
- Four high-risk classes now CI-enforced: field types, RLS, flow nodes, analytics.
- README governed-types + high-risk tables updated; changeset description updated.

Verified: liveness gate green (dataset 27 classified); 17 registry tests; the
analytics proof runs green; full dogfood suite 59/59.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XVdnfUAx85amkerym26vdx
@os-zhuang os-zhuang changed the title feat(spec,verify): prove-it-runs proof field + ratchet, and the flow-node Phase 2 proof (ADR-0054 #1 + Phase 2) feat(spec,verify): prove-it-runs proof field + ratchet, binding 4 high-risk classes (ADR-0054 #1 + Phase 2) Jun 19, 2026
@os-zhuang
os-zhuang marked this pull request as ready for review June 19, 2026 11:00
@os-zhuang
os-zhuang merged commit a8e4f3b into main Jun 19, 2026
18 checks passed
@os-zhuang
os-zhuang deleted the claude/lucid-gauss-t7dd3z branch June 19, 2026 11:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci/cd dependencies Pull requests that update a dependency file documentation Improvements or additions to documentation size/l tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants